function [label_cell,omeMeta] = bfopen_tvs(id,matpath)
%Edited TVS 012213 to build time vector, simplify indexing, use matfile
% A script for opening microscopy images in MATLAB using Bio-Formats.
%
% The function returns a list of image series; i.e., a cell array of cell
% arrays of (matrix, label) pairs, with each matrix representing a single
% image plane, and each inner list of matrices representing an image
% series. See below for examples of usage.
%
% Portions of this code were adapted from:
% http://www.mathworks.com/support/solutions/en/data/1-2WPAYR/
%
% This method is ~1.5x-2.5x slower than Bio-Formats's command line
% showinf tool (MATLAB 7.0.4.365 R14 SP2 vs. java 1.6.0_20),
% due to overhead from copying arrays.
%
% Thanks to all who offered suggestions and improvements:
%     * Ville Rantanen
%     * Brett Shoelson
%     * Martin Offterdinger
%     * Tony Collins
%     * Cris Luengo
%     * Arnon Lieber
%     * Jimmy Fong
%
% NB: Internet Explorer sometimes erroneously renames the Bio-Formats library
%     to loci_tools.zip. If this happens, rename it back to loci_tools.jar.
%
% For many examples of how to use the bfopen function, please see:
%     http://trac.openmicroscopy.org.uk/ome/wiki/BioFormats-Matlab

% -- Configuration - customize this section to your liking --

% Toggle the autoloadBioFormats flag to control automatic loading
% of the Bio-Formats library using the javaaddpath command.
%
% For static loading, you can add the library to MATLAB's class path:
%     1. Type "edit classpath.txt" at the MATLAB prompt.
%     2. Go to the end of the file, and add the path to your JAR file
%        (e.g., C:/Program Files/MATLAB/work/loci_tools.jar).
%     3. Save the file and restart MATLAB.
%
% There are advantages to using the static approach over javaaddpath:
%     1. If you use bfopen within a loop, it saves on overhead
%        to avoid calling the javaaddpath command repeatedly.
%     2. Calling 'javaaddpath' may erase certain global parameters.
autoloadBioFormats = 1;

% Toggle the stitchFiles flag to control grouping of similarly
% named files into a single dataset based on file numbering.
stitchFiles = 0;

% To work with compressed Evotec Flex, fill in your LuraWave license code.
%lurawaveLicense = 'xxxxxx-xxxxxxx';

% -- Main function - no need to edit anything past this point --

% load the Bio-Formats library into the MATLAB environment
status = bfCheckJavaPath(autoloadBioFormats);
assert(status, ['Missing Bio-Formats library. Either add loci_tools.jar '...
    'to the static Java path or add it to the Matlab path.']);

% Prompt for a file if not input
if nargin == 0 || exist(id, 'file') == 0
    [file, path] = uigetfile(bfGetFileExtensions, 'Choose a file to open');
    id = [path file];
    if isequal(path, 0) || isequal(file, 0), return; end
end

% initialize logging
loci.common.DebugTools.enableLogging('INFO');

% Get the channel filler % -- this step's speed is limited by read speed from the volume on network
r = bfGetReader(id, stitchFiles);
positions = r.getSeriesCount();
r.setSeries(0);
numImages = r.getImageCount();
[x,y,z,time,channels] = deal(r.getSizeX(),r.getSizeY(),r.getSizeZ(),r.getSizeT(),r.getSizeC());
%Open new matfile
m = matfile(matpath,'Writable',true);
%Initialize cell for I{p}(x,y,z,t,c). Can index into mat file,
%non-contiguous, each iteration as contiguous block (never perform
%operations on all channels or all positions)
disp(['Allocating space in matfile for cells...'])
tic
for p=1:positions
        m.I(p,1) = {zeros(x,y,z,time,channels,'uint16')};
end
toc
%Initialize matrix collector (positions)
I_p = zeros(x,y,z,time,channels,'uint16');
% Initialize time vector: 'ZTCP', double
m.time_v(prod([z time channels positions]),1) = 0;
ind=1;
% Initialize labels
label_cell = cell(positions,1);

%OME Metadata object
omeMeta = r.getMetadataStore();

h_bar = waitbar(0,'Converting to arrays from .nd2');
for p = 1:positions
    fprintf('Reading series #%d', p);
    r.setSeries(p - 1);
    for i = 1:numImages
        %disp(['     Image = ' num2str(i) '/' num2str(numImages)])
        % build an informative title for our figure
        label = id;
        if positions > 1
            qs = int2str(p);
            label = [label, '; series ', qs, '/', int2str(positions)];
        end
        if numImages > 1
            qi = int2str(i);
            label = [label, '; plane ', qi, '/', int2str(numImages)];
            if r.isOrderCertain()
                lz = 'Z';
                lc = 'C';
                lt = 'T';
            else
                lz = 'Z?';
                lc = 'C?';
                lt = 'T?';
            end
            zct = r.getZCTCoords(i - 1) + 1;
            sizeZ = r.getSizeZ();
            if sizeZ > 1
                qz = int2str(zct(1));
                label = [label, '; ', lz, '=', qz, '/', int2str(sizeZ)];
            end
            sizeC = r.getSizeC();
            if sizeC > 1
                qc = int2str(zct(2));
                label = [label, '; ', lc, '=', qc, '/', int2str(sizeC)];
            end
            sizeT = r.getSizeT();
            if sizeT > 1
                qt = int2str(zct(3));
                label = [label, '; ', lt, '=', qt, '/', int2str(sizeT)];
            end
        end
        % save image plane and label into the list
        % Final order needed is: {P}'XYZTC';
        I_p(:,:,zct(1),zct(3),zct(2)) = bfGetPlane(r, i);
        m.time_v(ind,1) = double(omeMeta.getPlaneDeltaT(p-1,i-1));
        ind=ind+1;
        label_cell{p} = label;
        %Status
        if rem(sum([p-1 i].*[numImages 1]),100) == 0
            waitbar(sum([p-1 i].*[numImages 1])/prod([positions numImages]),h_bar)
        end
    end
    disp('\nWriting to MAT')
    tic
    m.I(p,1) = {I_p};
    toc
    fprintf('\n');
end
r.close();
close(h_bar)
